import 'package:built_collection/built_collection.dart';
import 'package:backend.core/core/domain/entities/api/google_play/api_google_play_purchased_subscription.dart';
import 'package:backend.core/core/domain/entities/api/google_play/api_google_play_purchased_subscription_cancellation_info.dart';
import 'package:backend.core/core/domain/entities/api/google_play/api_google_play_purchased_subscription_pause_info.dart';
import 'package:backend.core/core/domain/entities/api/google_play/api_google_play_purchased_subscription_status.dart';
import 'package:backend.core/core/domain/entities/google_play/google_play_purchased_subscription_info.dart';
import 'package:backend.core/core/domain/entities/google_play/google_play_purchased_subscription_transaction.dart';
import 'package:backend.purchases/domain/helpers/api/google_play/create_api_google_play_purchased_item_acknowledgement_status_from_internal_one.dart';
import 'package:backend.purchases/domain/helpers/api/google_play/create_api_google_play_purchased_subscription_cancellation_info_from_internal_one.dart';
import 'package:backend.purchases/domain/helpers/api/google_play/create_api_google_play_purchased_subscription_pause_info_from_internal_one.dart';
import 'package:backend.purchases/domain/helpers/api/google_play/create_api_google_play_purchased_subscription_price_change_status_from_internal_one.dart';
import 'package:backend.purchases/domain/helpers/api/google_play/create_api_google_play_purchased_subscription_transaction_from_internal_one.dart';

abstract class CreateApiGooglePlayPurchasedSubscriptionFromInternalOne {
  ApiGooglePlayPurchasedSubscription call({
    required GooglePlayPurchasedSubscriptionInfo purchasedSubscriptionInfo,
    required BuiltList<GooglePlayPurchasedSubscriptionTransaction>
        purchasedSubscriptionTransactions,
  });
}

class CreateApiGooglePlayPurchasedSubscriptionFromInternalOneImpl
    implements CreateApiGooglePlayPurchasedSubscriptionFromInternalOne {
  const CreateApiGooglePlayPurchasedSubscriptionFromInternalOneImpl({
    required CreateApiGooglePlayPurchasedSubscriptionTransactionFromInternalOne
        createApiGooglePlayPurchasedSubscriptionTransactionFromInternalOne,
    required CreateApiGooglePlayPurchasedSubscriptionPriceChangeStatusFromInternalOne
        createApiGooglePlayPurchasedSubscriptionPriceChangeStatusFromInternalOne,
    required CreateApiGooglePlayPurchasedSubscriptionCancellationInfoFromInternalOne
        createApiGooglePlayPurchasedSubscriptionCancellationInfoFromInternalOne,
    required CreateApiGooglePlayPurchasedSubscriptionPauseInfoFromInternalOne
        createApiGooglePlayPurchasedSubscriptionPauseInfoFromInternalOne,
    required CreateApiGooglePlayPurchasedItemAcknowledgementStatusFromInternalOne
        createApiGooglePlayPurchasedItemAcknowledgementStatusFromInternalOne,
  })  : _createApiGooglePlayPurchasedSubscriptionTransactionFromInternalOne =
            createApiGooglePlayPurchasedSubscriptionTransactionFromInternalOne,
        _createApiGooglePlayPurchasedSubscriptionPriceChangeStatusFromInternalOne =
            createApiGooglePlayPurchasedSubscriptionPriceChangeStatusFromInternalOne,
        _createApiGooglePlayPurchasedSubscriptionCancellationInfoFromInternalOne =
            createApiGooglePlayPurchasedSubscriptionCancellationInfoFromInternalOne,
        _createApiGooglePlayPurchasedSubscriptionPauseInfoFromInternalOne =
            createApiGooglePlayPurchasedSubscriptionPauseInfoFromInternalOne,
        _createApiGooglePlayPurchasedItemAcknowledgementStatusFromInternalOne =
            createApiGooglePlayPurchasedItemAcknowledgementStatusFromInternalOne;

  final CreateApiGooglePlayPurchasedSubscriptionTransactionFromInternalOne
      _createApiGooglePlayPurchasedSubscriptionTransactionFromInternalOne;
  final CreateApiGooglePlayPurchasedSubscriptionPriceChangeStatusFromInternalOne
      _createApiGooglePlayPurchasedSubscriptionPriceChangeStatusFromInternalOne;
  final CreateApiGooglePlayPurchasedSubscriptionCancellationInfoFromInternalOne
      _createApiGooglePlayPurchasedSubscriptionCancellationInfoFromInternalOne;
  final CreateApiGooglePlayPurchasedSubscriptionPauseInfoFromInternalOne
      _createApiGooglePlayPurchasedSubscriptionPauseInfoFromInternalOne;
  final CreateApiGooglePlayPurchasedItemAcknowledgementStatusFromInternalOne
      _createApiGooglePlayPurchasedItemAcknowledgementStatusFromInternalOne;

  @override
  ApiGooglePlayPurchasedSubscription call({
    required GooglePlayPurchasedSubscriptionInfo purchasedSubscriptionInfo,
    required BuiltList<GooglePlayPurchasedSubscriptionTransaction>
        purchasedSubscriptionTransactions,
  }) {
    final apiPriceChangeStatus =
        _createApiGooglePlayPurchasedSubscriptionPriceChangeStatusFromInternalOne(
      priceChangeStatus: purchasedSubscriptionInfo.priceChangeStatus,
    );

    ApiGooglePlayPurchasedSubscriptionCancellationInfo? apiCancellationInfo;

    if (purchasedSubscriptionInfo.cancellationInfo != null) {
      apiCancellationInfo =
          _createApiGooglePlayPurchasedSubscriptionCancellationInfoFromInternalOne(
        cancellationInfo: purchasedSubscriptionInfo.cancellationInfo!,
      );
    }

    ApiGooglePlayPurchasedSubscriptionPauseInfo? apiPauseInfo;

    if (purchasedSubscriptionInfo.pauseInfo != null) {
      apiPauseInfo = _createApiGooglePlayPurchasedSubscriptionPauseInfoFromInternalOne(
        pauseInfo: purchasedSubscriptionInfo.pauseInfo!,
      );
    }

    final apiTransactions = purchasedSubscriptionTransactions.map((transaction) {
      return _createApiGooglePlayPurchasedSubscriptionTransactionFromInternalOne(
        transaction: transaction,
      );
    }).toList();

    apiTransactions.sort((first, second) {
      return first.time.compareTo(second.time);
    });

    final unrevokedTransactions = purchasedSubscriptionTransactions.where((transaction) {
      return transaction.revocationInfo == null;
    }).toList();

    GooglePlayPurchasedSubscriptionTransaction? lastUnrevokedTransaction;

    if (unrevokedTransactions.isNotEmpty) {
      lastUnrevokedTransaction = unrevokedTransactions.last;
    }

    final currentTime = DateTime.now().toUtc();

    final ApiGooglePlayPurchasedSubscriptionStatus apiStatus;

    if (lastUnrevokedTransaction == null) {
      apiStatus = ApiGooglePlayPurchasedSubscriptionStatus.revoked;
    } else if (apiPauseInfo != null) {
      apiStatus = ApiGooglePlayPurchasedSubscriptionStatus.paused;
    } else if (lastUnrevokedTransaction.expirationTime.isBefore(currentTime)) {
      apiStatus = ApiGooglePlayPurchasedSubscriptionStatus.expired;
    } else {
      apiStatus = ApiGooglePlayPurchasedSubscriptionStatus.active;
    }

    final apiAcknowledgementStatus =
        _createApiGooglePlayPurchasedItemAcknowledgementStatusFromInternalOne(
      acknowledgementStatus: purchasedSubscriptionInfo.acknowledgementStatus,
    );

    return ApiGooglePlayPurchasedSubscription(
      purchaseItemSku: purchasedSubscriptionInfo.purchaseItemSku,
      purchaseToken: purchasedSubscriptionInfo.purchaseToken,
      test: purchasedSubscriptionInfo.test,
      startTime: purchasedSubscriptionInfo.startTime,
      autoRenewalEnabled: purchasedSubscriptionInfo.autoRenewalEnabled,
      acknowledgementStatus: apiAcknowledgementStatus,
      status: apiStatus,
      expirationTime: lastUnrevokedTransaction?.expirationTime,
      priceChangeStatus: apiPriceChangeStatus,
      cancellationInfo: apiCancellationInfo,
      pauseInfo: apiPauseInfo,
      transactions: apiTransactions.toBuiltList(),
    );
  }
}
